package com.dataseek.iot.operation.manager.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dataseek.iot.core.constant.ResponseConst;
import com.dataseek.iot.core.constant.SystemConst;
import com.dataseek.iot.core.jwt.JwtTokenProvider;
import com.dataseek.iot.core.request.QueryPage2;
import com.dataseek.iot.core.response.ResponseEntity;
import com.dataseek.iot.core.util.AuthUtil;
import com.dataseek.iot.core.util.ParseUtil;
import com.dataseek.iot.mysql.entity.*;
import com.dataseek.iot.mysql.service.impl.DeviceRecordServiceImpl;
import com.dataseek.iot.mysql.service.impl.DeviceServiceImpl;
import com.dataseek.iot.mysql.service.impl.UserServiceImpl;
import com.dataseek.iot.operation.manager.util.ChartUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import java.util.*;

import static com.dataseek.iot.core.constant.DataConst.TEMP_MAP;

/**
 * @author cc
 * @Title: 设备运行监控服务
 * @Description: 设备运行监控服务
 * @date 2021/10/295:09 下午
 * @since 1.0
 */
@RestController
@RequestMapping("/monitor")
@Api(tags = "设备运维监控")
@Slf4j
public class DeviceMonitorController {

    @Autowired
    DeviceServiceImpl deviceService;

    @Autowired
    DeviceRecordServiceImpl deviceRecordService;

    @Autowired
    UserServiceImpl userService;

    Map<String, List> result = new LinkedHashMap<>();

    @Autowired
    JwtTokenProvider jwtTokenProvider;

    @PostMapping("/device/page")
    @ApiOperation("设备监控列表")
    public Flux<ResponseEntity> deviceList(@RequestBody JSONObject queryParams, ServerWebExchange exchange){
        ResponseEntity entity = new ResponseEntity();
        String username = AuthUtil.getUsername(exchange,jwtTokenProvider);
        LoginUser loginUser =  userService.selectAllUserDetails(username);
        String roleCode = loginUser.getRoleCode();
        List result = new ArrayList();
        Page p =  new Page();
        try{
            if(roleCode.equals(SystemConst.SUPER_USER)){
                QueryPage2 queryPage2 = ParseUtil.parseJsonWithPage(queryParams);
                p = deviceService.page(queryPage2.getPage(),queryPage2.getWrapper());
                entity.setCode(ResponseConst.SUCCESS_CODE);
                entity.setMsg(ResponseConst.SUCCESS);
                entity.setData(p);
            }else if(Objects.nonNull(queryParams)&&queryParams.containsKey("line_code")){
                String[] codes = queryParams.getString("line_code").split(",");
                for (String code : codes){
                    queryParams.put("line_code", code);
                    QueryPage2 queryPage2 = ParseUtil.parseJsonWithPage(queryParams);
                    p = deviceService.page(queryPage2.getPage(),queryPage2.getWrapper());
                    List list = p.getRecords();
                    result.addAll(list);
                }
                p.setRecords(result);
                entity.setCode(ResponseConst.SUCCESS_CODE);
                entity.setMsg(ResponseConst.SUCCESS);
                entity.setData(p);
            }
        }catch (Exception e){
            entity.setCode(ResponseConst.CRUD_FAILED_CODE);
            entity.setMsg(ResponseConst.CRUD_FAILED);
            entity.setMsg(e.getMessage());
            e.printStackTrace();
        }
        return Flux.just(entity);
    }


    @GetMapping("/device/detailInDay/{code}/{num}")
    @ApiOperation("设备详情信息, code 为设备编码，num为回溯几天")
    public Flux<ResponseEntity> deviceDetailInDay(@PathVariable String code, @PathVariable Integer num){
        ResponseEntity entity = new ResponseEntity();
        List<String> codes = deviceService.getDictNames(code, true);
        try{
            List<DeviceRecord> records = deviceRecordService.getRecordsInHour(code, num);
            for(DeviceRecord record : records){
                JSONObject jsonRecord = (JSONObject) JSON.toJSON(record);
                ChartUtil.createCells(record.getCreateTime(), codes, jsonRecord);
            }

            entity.setCode(ResponseConst.SUCCESS_CODE);
            entity.setMsg(ResponseConst.SUCCESS);
            entity.setData(TEMP_MAP);
        }catch (Exception e){
            entity.setCode(ResponseConst.CRUD_FAILED_CODE);
            entity.setMsg(ResponseConst.CRUD_FAILED);
            entity.setData(e.getMessage());
        }finally {
            TEMP_MAP.clear();
        }
        return Flux.just(entity);
    }

    @GetMapping("/device/detailInHour/{code}/{num}")
    @ApiOperation("设备详情信息, code 为设备编码，num为回溯几小时")
    public Flux<ResponseEntity> deviceDetailInHour(@PathVariable String code, @PathVariable Integer num){
        TEMP_MAP.clear();
        ResponseEntity entity = new ResponseEntity();
        List<String> codes = deviceService.getDictNames(code, true);
        try{
            List<DeviceRecord> records = deviceRecordService.getRecordsInHour(code, num);
            for(DeviceRecord record : records){
                JSONObject jsonRecord = (JSONObject) JSON.toJSON(record);
                ChartUtil.createCells(record.getCreateTime(), codes, jsonRecord);
            }

            entity.setCode(ResponseConst.SUCCESS_CODE);
            entity.setMsg(ResponseConst.SUCCESS);
            entity.setData(TEMP_MAP);
        }catch (Exception e){
            entity.setCode(ResponseConst.CRUD_FAILED_CODE);
            entity.setMsg(ResponseConst.CRUD_FAILED);
            entity.setData(e.getMessage());
            e.printStackTrace();
        }
        return Flux.just(entity);
    }

    @GetMapping("/device/paramInDay/{deviceCode}/{property}/{pastDay}")
    @ApiOperation("参数历史数据, deviceCode: 设备编码；property：参数名称；pastDay: 多少天以内的数据")
    public Flux<ResponseEntity> paramHistoryInDay(@PathVariable String deviceCode,
                                             @PathVariable String property,
                                             @PathVariable Integer pastDay){
        ResponseEntity entity = new ResponseEntity();
        try{
            List result =  deviceRecordService.getPropertyHistory(deviceCode, property, pastDay);
            entity.setCode(ResponseConst.SUCCESS_CODE);
            entity.setMsg(ResponseConst.SUCCESS);
            entity.setData(result);
        }catch (Exception e){
            entity.setCode(ResponseConst.CRUD_FAILED_CODE);
            entity.setMsg(ResponseConst.CRUD_FAILED);
            entity.setData(e.getMessage());
        }
        return Flux.just(entity);
    }


    @GetMapping("/device/paramInHour/{deviceCode}/{property}/{hour}")
    @ApiOperation("参数历史数据, deviceCode: 设备编码；property：参数名称；hour: 多少小时以内的数据")
    public Flux<ResponseEntity> paramHistoryInHour(@PathVariable String deviceCode,
                                             @PathVariable String property,
                                             @PathVariable Integer hour){
        ResponseEntity entity = new ResponseEntity();
        try{
            List result =  deviceRecordService.getPropertyHistoryByHour(deviceCode, property, hour);
            entity.setCode(ResponseConst.SUCCESS_CODE);
            entity.setMsg(ResponseConst.SUCCESS);
            entity.setData(result);
        }catch (Exception e){
            entity.setCode(ResponseConst.CRUD_FAILED_CODE);
            entity.setMsg(ResponseConst.CRUD_FAILED);
            entity.setData(e.getMessage());
        }
        return Flux.just(entity);
    }



}
